﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
using YArchitech.Revit;
using YJKArch.Utils;

namespace YJKArch.Ramp.Utils
{
	public class DoubleLineCliper
	{
		public DoubleLineCliper(Autodesk.Revit.ApplicationServices.Application app)
		{
			this.m_App = app;
		}

		public List<ThreeLine> CalculaterDoubleLine(List<Curve> curves, List<double> leftWidth, List<double> rightWidth)
		{
			List<ThreeLine> list = this.OffsetDoubleLine(curves, leftWidth, rightWidth);
			if (list.Count == 1)
			{
				return list;
			}
			for (int i = 0; i < list.Count - 1; i++)
			{
				ThreeLine value = list[i];
				int index = i + 1;
				if (i == list.Count - 1)
				{
					index = 0;
				}
				ThreeLine value2 = list[index];
				this.ClippingSideLine(ref value, ref value2);
				list[i] = value;
				list[index] = value2;
			}
			return list;
		}

		protected void ClippingSideLine(ref ThreeLine curThrLine, ref ThreeLine nextThrLine)
		{
			XYZ endPoint = curThrLine.CenterLine.EndPoint;
			EdgeInfo leftLine = curThrLine.LeftLine;
			EdgeInfo leftLine2 = nextThrLine.LeftLine;
			if (!leftLine.IsPoint && !leftLine2.IsPoint)
			{
				XYZ xyz = Geometry.IntersectWithTwoCurves(leftLine.ConvertTo(this.m_App), leftLine2.ConvertTo(this.m_App), endPoint, true, true, this.m_App);
				if (xyz != null)
				{
					curThrLine.LeftLine = this.ResetEndWithCurve(leftLine, endPoint, xyz);
					nextThrLine.LeftLine = this.ResetEndWithCurve(leftLine2, endPoint, xyz);
				}
			}
			EdgeInfo rightLine = curThrLine.RightLine;
			EdgeInfo rightLine2 = nextThrLine.RightLine;
			if (!rightLine.IsPoint && !rightLine2.IsPoint)
			{
				XYZ xyz2 = Geometry.IntersectWithTwoCurves(rightLine.ConvertTo(this.m_App), rightLine2.ConvertTo(this.m_App), endPoint, true, true, this.m_App);
				if (xyz2 != null)
				{
					curThrLine.RightLine = this.ResetEndWithCurve(rightLine, endPoint, xyz2);
					nextThrLine.RightLine = this.ResetEndWithCurve(rightLine2, endPoint, xyz2);
				}
			}
		}

		protected EdgeInfo ResetEndWithCurve(EdgeInfo curve, XYZ curNode, XYZ newPoint)
		{
			XYZ startPoint = curve.StartPoint;
			XYZ endPoint = curve.EndPoint;
			double num = curNode.DistanceTo(startPoint);
			double num2 = curNode.DistanceTo(endPoint);
			if (!curve.IsArc)
			{
				if (num > num2)
				{
					return new EdgeInfo(startPoint, newPoint, 0.0);
				}
				return new EdgeInfo(newPoint, endPoint, 0.0);
			}
			else
			{
				XYZ center = curve.Center;
				bool isAnticlockwise = true;
				if (Geometry.LessThan(curve.Bulge, 0.0))
				{
					isAnticlockwise = false;
				}
				if (num > num2)
				{
					double bulge = Geometry.GetBulge(startPoint, newPoint, center, isAnticlockwise);
					return new EdgeInfo(startPoint, newPoint, bulge);
				}
				double bulge2 = Geometry.GetBulge(newPoint, endPoint, center, isAnticlockwise);
				return new EdgeInfo(newPoint, endPoint, bulge2);
			}
		}

		protected List<ThreeLine> OffsetDoubleLine(List<Curve> curves, List<double> leftWidth, List<double> rightWidth)
		{
			List<ThreeLine> list = new List<ThreeLine>();
			for (int i = 0; i < curves.Count; i++)
			{
				Curve curve = curves[i];
				XYZ hyendPoint = curve.GetEndPoint(0);
				XYZ hyendPoint2 = curve.GetEndPoint(1);
				Line line = curve as Line;
				if (null != line)
				{
					EdgeInfo edgeInfo = new EdgeInfo(hyendPoint, hyendPoint2, 0.0);
					EdgeInfo leftLine = EdgeInfo.Offset(edgeInfo, leftWidth[i]);
					EdgeInfo rightLine = EdgeInfo.Offset(edgeInfo, -rightWidth[i]);
					ThreeLine item = new ThreeLine(i, edgeInfo, leftLine, rightLine);
					list.Add(item);
				}
				else
				{
					Arc arc = curve as Arc;
					if (null != arc)
					{
						bool flag = true;
						if (arc.Normal.IsAlmostEqualTo(-XYZ.BasisZ))
						{
							flag = false;
						}
						double bulge = Geometry.GetBulge(hyendPoint, hyendPoint2, arc.Center, flag);
						EdgeInfo edgeInfo2 = new EdgeInfo(hyendPoint, hyendPoint2, bulge);
						double num = -1.0;
						if (flag)
						{
							num = 1.0;
						}
						EdgeInfo leftLine2 = EdgeInfo.Offset(edgeInfo2, -leftWidth[i] * num);
						EdgeInfo rightLine2 = EdgeInfo.Offset(edgeInfo2, rightWidth[i] * num);
						ThreeLine item2 = new ThreeLine(i, edgeInfo2, leftLine2, rightLine2);
						list.Add(item2);
					}
				}
			}
			return list;
		}

		private Application m_App;
	}
}
